#include "stdafx.h"

int TWS::GetNewOrderID()
{
	cur_order_id++;
	return cur_order_id - 1;
}

int TWS::GetNewID()
{
	cur_id++;
	return cur_id - 1;
}

void TWS::NewOrder(Trigger ^trg, OrderType ordT)
{
	int new_order_id = GetNewOrderID();

	TWSLib::IContract ^ic;
	TWSLib::IOrder ^ord;

	ic = tws->createContract();
	ord = tws->createOrder();

	ic->symbol = trg->SymbolName;
	ic->secType = "STK";
	ic->currency = "USD";
	ic->exchange = "SMART";

	if (trg->Trend == sLONG) ord->action = "SELL";
	if (trg->Trend == sSHORT) ord->action = "BUY";

	if (ordT == oTrigger) 
	{
		ord->totalQuantity = trg->Quantity;
		trg->triggerOrderID = new_order_id;
		ord->orderType = "STPLMT";
		ord->lmtPrice = Math::Round((double)trg->TriggerLimitPrice, 2);
		ord->auxPrice = Math::Round((double)trg->TriggerStopPrice, 2);
		if (trg->Trend == sLONG) ord->action = "BUY";
		if (trg->Trend == sSHORT) ord->action = "SELL";
	}
	if (ordT == oLimit_1) 
	{
		ord->totalQuantity = trg->LimitP->Profit_1_size;
		trg->limit_1_OrderID = new_order_id;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_1_price, 2);
	}
	if (ordT == oLimit_2) 
	{
		ord->totalQuantity = trg->LimitP->Profit_2_size;
		trg->limit_2_OrderID = new_order_id;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_2_price, 2);
	}
	if (ordT == oLimit_3) 
	{
		ord->totalQuantity = trg->LimitP->Profit_3_size;
		trg->limit_3_OrderID = new_order_id;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_3_price, 2);
	}
	if (ordT == oLimit_4) 
	{
		ord->totalQuantity = trg->LimitP->Profit_4_size;
		trg->limit_4_OrderID = new_order_id;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_4_price, 2);
	}
	if (ordT == oStop)
	{
		ord->totalQuantity = trg->QuantityFilled - trg->LimitP->Profit_1_filled - trg->LimitP->Profit_2_filled - trg->LimitP->Profit_3_filled - trg->LimitP->Profit_4_filled;
		trg->stopOrderID = new_order_id;
		ord->orderType = "LMT";
		if (trg->Trend == sLONG) ord->lmtPrice = Math::Round((double)trg->StopLossPrice, 2) - Math::Round((double)(trg->StopLossSpread * trg->RiskByCents / 100), 2);
		if (trg->Trend == sSHORT) ord->lmtPrice = Math::Round((double)trg->StopLossPrice, 2) + Math::Round((double)(trg->StopLossSpread * trg->RiskByCents / 100), 2);
	}
	if (ordT == oStopMKT)
	{
		ord->totalQuantity = trg->QuantityFilled - trg->LimitP->Profit_1_filled - trg->LimitP->Profit_2_filled - trg->LimitP->Profit_3_filled - trg->LimitP->Profit_4_filled;
		trg->stopOrderID = new_order_id;
		ord->orderType = "MKT";
		ord->auxPrice = Math::Round((double)trg->StopLossPrice, 2);
	}
	if (trg->AccountP->UseAdvisorAcc == true)
	{
		ord->faGroup = trg->AccountP->Allocation;
		ord->faMethod = "EqualQuantity";
		if (ordT == oTrigger) ord->totalQuantity *= trg->AccountP->SubAcc;
	}

	tws->placeOrderEx(new_order_id, ic, ord);
}

void TWS::UpdateOrder(Trigger ^trg, OrderType ordT)
{
	int order_id;
	TWSLib::IContract ^ic;
	TWSLib::IOrder ^ord;

	ic = tws->createContract();
	ord = tws->createOrder();

	ic->symbol = trg->SymbolName;
	ic->secType = "STK";
	ic->currency = "USD";
	ic->exchange = "SMART";

	if (trg->Trend == sLONG) ord->action = "SELL";
	if (trg->Trend == sSHORT) ord->action = "BUY";

	if (ordT == oLimit_1) 
	{
		ord->totalQuantity = trg->LimitP->Profit_1_size;
		order_id = trg->limit_1_OrderID = trg->Limit_1_OrderID;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_1_price, 2);
	}
	if (ordT == oLimit_2) 
	{
		ord->totalQuantity = trg->LimitP->Profit_2_size;
		order_id = trg->limit_2_OrderID = trg->Limit_2_OrderID;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_2_price, 2);
	}
	if (ordT == oLimit_3) 
	{
		ord->totalQuantity = trg->LimitP->Profit_3_size;
		order_id = trg->limit_3_OrderID = trg->Limit_3_OrderID;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_3_price, 2);
	}
	if (ordT == oLimit_4) 
	{
		ord->totalQuantity = trg->LimitP->Profit_4_size;
		order_id = trg->limit_4_OrderID = trg->Limit_4_OrderID;
		ord->orderType = "LMT";
		ord->lmtPrice = Math::Round((double)trg->LimitP->Profit_4_price, 2);
	}
	if (trg->AccountP->UseAdvisorAcc == true)
	{
		ord->faGroup = trg->AccountP->Allocation;
		ord->faMethod = "EqualQuantity";
	}

	tws->placeOrderEx(order_id, ic, ord);
}

void TWS::CancelOrder(int ord_num)
{
	tws->cancelOrder(ord_num);
}

void TWS::UpdateID(System::Object^ sender, AxTWSLib::_DTwsEvents_nextValidIdEvent^ e)
{
	cur_order_id = e->id;
}

TWSLib::IContract^ TWS::CreateContract()
{
	return tws->createContract();
}

TWS::TWS(AxTWSLib::AxTws ^tws_pointer)
{
	cur_id = 0;
	tws = tws_pointer;
	tws->connect("127.0.0.1", 7496, 0);
	if (tws->serverVersion <= 0)
		throw "Can't connect to IB!";

	tws->nextValidId += gcnew AxTWSLib::_DTwsEvents_nextValidIdEventHandler(this, &TWS::UpdateID);
	tws_pointer->reqIds(1);
}
